home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / mplayer.c < prev    next >
C/C++ Source or Header  |  1992-12-13  |  8KB  |  312 lines

  1. /*    SCCS Id: @(#)mplayer.c    3.1    92/10/28    */
  2. /*    Copyright (c) Izchak Miller, 1992.              */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. static const char *NDECL(dev_name);
  8. static void FDECL(get_mplname, (struct monst *, char *));
  9. static void FDECL(mk_mplayer_armor, (struct monst *, int, int));
  10.  
  11. /* These are the names of those who
  12.  * contributed to the development of NetHack 3.1.
  13.  *
  14.  * Keep in alphabetical order within teams.
  15.  * Same first name is entered once within each team.
  16.  */
  17. static const char *developers[] = {
  18.     /* devteam */
  19.     "Dave", "Dean", "Eric", "Izchak", "Janet", "Jessie",
  20.     "Ken", "Kevin", "Matt", "Mike", "Pat", "Steve", "Timo",
  21.     /* PC team */
  22.     "Bill", "Carl", "John", "Kevin", "Mike", "Norm", "Paul",
  23.     "Stephen", "Steve",
  24.     /* Amiga team */
  25.     "Greg", "Gregg", "Keni", "Mike", "Olaf", "Richard",
  26.     /* Mac team */
  27.     "David", "Johnny", "Jon", "Jonathan", "Michael", "Rob",
  28.     "Tim", "Wang",
  29.     /* OS/2 team */
  30.     "Timo",
  31.     /* Atari team */
  32.     "Eric",
  33.     /* VMS team */
  34.     "Joshua", "Pat",
  35.     ""};
  36.  
  37.  
  38. /* return a randomly chosen developer name */
  39. static const char *
  40. dev_name() 
  41. {
  42.     register int i, m = 0, n = SIZE(developers);
  43.     register struct monst *mtmp;
  44.     register boolean match;
  45.  
  46.     do {
  47.         match = FALSE;
  48.         i = rn2(n);
  49.         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 
  50.         if(!is_mplayer(mtmp->data)) continue;
  51.         if(!strncmp(developers[i], NAME(mtmp),
  52.                            strlen(developers[i]))) {
  53.             match = TRUE;
  54.             break;
  55.             }
  56.         }
  57.         m++;
  58.     } while (match && m < 100); /* m for insurance */
  59.  
  60.     if (match) return NULL;
  61.     return(developers[i]);
  62. }
  63.  
  64. static void
  65. get_mplname(mtmp, nam)
  66. register struct monst *mtmp;
  67. char *nam;
  68. {
  69.     boolean fmlkind = is_female(mtmp->data);
  70.     const char *devnam;
  71.  
  72.     devnam = dev_name();
  73.     if (!devnam)
  74.         Strcpy(nam, fmlkind ? "Eve" : "Adam");
  75.     else if (fmlkind && !!strcmp(devnam, "Janet"))
  76.         Strcpy(nam, rn2(2) ? "Maud" : "Eve");
  77.     else Strcpy(nam, devnam);
  78.  
  79.     if (fmlkind || !strcmp(nam, "Janet"))
  80.         mtmp->female = 1;
  81.     else
  82.         mtmp->female = 0;
  83.     Strcat(nam, " the ");
  84.     Strcat(nam, rank_of((unsigned)rn1(12, 20), 
  85.                highc(mtmp->data->mname[0]), (boolean)mtmp->female));
  86. }
  87.  
  88. static void
  89. mk_mplayer_armor(mon, range1, range2)
  90. struct monst *mon;
  91. int range1, range2;
  92. {
  93.     struct obj *obj;
  94.  
  95.     obj = mksobj(rnd_class(range1, range2), FALSE, FALSE);
  96.     if (!rn2(3)) obj->oerodeproof = 1;
  97.     if (!rn2(3)) curse(obj);
  98.     if (!rn2(3)) bless(obj);
  99.     /* Most players who get to the endgame who have cursed equipment
  100.      * have it because the wizard or other monsters cursed it, so its
  101.      * chances of having plusses is the same as usual....
  102.      */
  103.     obj->spe = rn2(10) ? (rn2(3) ? rn2(5) : rn1(4,4)) : -rnd(3);
  104.     mpickobj(mon, obj);
  105. }
  106.  
  107. struct monst *
  108. mk_mplayer(ptr, x, y, special)
  109. register struct permonst *ptr;
  110. xchar x, y;
  111. register boolean special;
  112. {
  113.     register struct monst *mtmp;
  114.     char nam[PL_NSIZ];
  115.  
  116.     if(!is_mplayer(ptr)) 
  117.         return((struct monst *)0);
  118.  
  119.     if(MON_AT(x, y))
  120.         rloc(m_at(x, y)); /* insurance */
  121.  
  122.     if(!In_endgame(&u.uz)) special = FALSE;
  123.  
  124.     if ((mtmp = makemon(ptr, x, y)) != 0) {
  125.         int weapon, quan;
  126.         struct obj *otmp;
  127.  
  128.         mtmp->m_lev = (special ? rn1(8,12) : rnd(16));
  129.         mtmp->mhp = mtmp->mhpmax = (special ?
  130.                           (d((int)mtmp->m_lev,10) + 30 + rnd(30)) :
  131.                           (d((int)mtmp->m_lev,10) + 30));
  132.         if(special) {
  133.             get_mplname(mtmp, nam);
  134.             mtmp = christen_monst(mtmp, nam);
  135.         }
  136.         mtmp->mpeaceful = 0;
  137.         set_malign(mtmp); /* peaceful may have changed again */
  138.         if(special && In_endgame(&u.uz))
  139.         /* that's why they are "stuck" in the endgame :-) */
  140.         (void)mongets(mtmp, FAKE_AMULET_OF_YENDOR);
  141.         switch(monsndx(ptr)) {
  142.         case PM_ARCHEOLOGIST:
  143.             weapon = BULLWHIP;
  144.             break;
  145.         case PM_BARBARIAN:
  146.             weapon = rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE;
  147.             break;
  148.         case PM_CAVEMAN:
  149.         case PM_CAVEWOMAN:
  150.             weapon = CLUB;
  151.             break;
  152.         case PM_ELF:
  153.             weapon = ELVEN_SHORT_SWORD;
  154.             break;
  155.         case PM_HEALER:
  156.             weapon = SCALPEL;
  157.             break;
  158.         case PM_KNIGHT:
  159.             weapon = LONG_SWORD;
  160.             break;
  161.         case PM_PRIEST:
  162.         case PM_PRIESTESS:
  163.             weapon = MACE;
  164.             break;
  165.         case PM_ROGUE:
  166.             weapon = SHORT_SWORD;
  167.             break;
  168.         case PM_SAMURAI:
  169.             weapon = KATANA;
  170.             break;
  171. #ifdef TOURIST
  172.         case PM_TOURIST:
  173.             weapon = 0;
  174.             break;
  175. #endif
  176.         case PM_VALKYRIE:
  177.             weapon = LONG_SWORD;
  178.             break;
  179.         case PM_WIZARD:
  180.             weapon = ATHAME;
  181.             break;
  182.         default: impossible("bad mplayer monster");
  183.             weapon = 0;
  184.             break;
  185.         }
  186.         if (rn2(2) && weapon)
  187.         otmp = mksobj(weapon, TRUE, FALSE);
  188.         else
  189.         otmp = mksobj(rn2(2) ? LONG_SWORD : 
  190.                   rnd_class(SPEAR, BULLWHIP), TRUE, FALSE);
  191.         otmp->spe = (special ? rn1(5,4) : rn2(4));
  192.         if (!rn2(3)) otmp->oerodeproof = 0;
  193.         if(special) {
  194.             /* probably the player got most artifacts anyway. */
  195.             if(In_endgame(&u.uz) && rn2(2)) 
  196.                   otmp = mk_artifact(otmp, A_NONE);
  197.             mpickobj(mtmp, otmp);
  198.             if (!rn2(10))
  199.             (void) mongets(mtmp, rn2(3) ? LUCKSTONE : LOADSTONE);
  200.             if (rn2(8))
  201.             mk_mplayer_armor(mtmp, ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY);
  202.             if (!rn2(3))
  203.             mk_mplayer_armor(mtmp, GRAY_DRAGON_SCALE_MAIL,
  204.             YELLOW_DRAGON_SCALE_MAIL);
  205.             else if (rn2(15))
  206.             mk_mplayer_armor(mtmp, PLATE_MAIL, CHAIN_MAIL);
  207.             if (rn2(8))
  208.             mk_mplayer_armor(mtmp, ELVEN_SHIELD, 
  209.                                SHIELD_OF_REFLECTION);
  210.             if (rn2(8))
  211.             mk_mplayer_armor(mtmp, LEATHER_GLOVES, 
  212.                                GAUNTLETS_OF_DEXTERITY);
  213.             if (rn2(8))
  214.             mk_mplayer_armor(mtmp, LOW_BOOTS, LEVITATION_BOOTS);
  215. #ifdef MUSE
  216.             /* Not clear what to do without MUSE. */
  217.             m_dowear(mtmp, TRUE);
  218. #endif
  219.             quan = rn2(3) ? rn2(3) : rn2(16);
  220.             while(quan--)
  221.             (void)mongets(mtmp, rnd_class(DILITHIUM_CRYSTAL, JADE));
  222.             /* To get the gold "right" would mean a player can double his */
  223.             /* gold supply by killing one mplayer.  Not good. */
  224.             mtmp->mgold = rn2(1000);
  225.             quan = rn2(10);
  226.             while(quan--)
  227.             mpickobj(mtmp, mkobj(RANDOM_CLASS, FALSE));
  228.         }
  229. #ifdef MUSE
  230.         quan = rnd(3);
  231.         while(quan--)
  232.         (void)mongets(mtmp, rnd_offensive_item(mtmp));
  233.         quan = rnd(3);
  234.         while(quan--)
  235.         (void)mongets(mtmp, rnd_defensive_item(mtmp));
  236.         quan = rnd(3);
  237.         while(quan--)
  238.         (void)mongets(mtmp, rnd_misc_item(mtmp));
  239. #endif
  240.     }
  241.  
  242.     return(mtmp);
  243. }
  244.  
  245. /* create the indicated number (num) of monster-players,
  246.  * randomly chosen, and in randomly chosen (free) locations
  247.  * on the level.  If "special", the size of num should not
  248.  * be bigger than the number of _non-repeated_ names in the
  249.  * developers array, otherwise a bunch of Adams and Eves will
  250.  * fill up the overflow.
  251.  */
  252. void
  253. create_mplayers(num, special)
  254. register int num;
  255. boolean special;
  256. {
  257.     register int pm, x, y;
  258.  
  259.     while(num) {
  260.         int tryct = 0;
  261.  
  262.         /* roll for character class */
  263.         pm = PM_ARCHEOLOGIST + rn2(PM_WIZARD - PM_ARCHEOLOGIST + 1);
  264.  
  265.         /* roll for an available location */
  266.         do {
  267.             x = rn1(COLNO-4, 2);
  268.             y = rnd(ROWNO-2);
  269.         } while(!goodpos(x, y, (struct monst *)0, &mons[pm]) ||
  270.              tryct++ >= 50);
  271.  
  272.         /* if pos not found in 50 tries, don't bother to continue */
  273.         if(tryct > 50) return;
  274.  
  275.         (void) mk_mplayer(&mons[pm], (xchar)x, (xchar)y, special);
  276.         num--;
  277.     }
  278. }
  279.  
  280. void
  281. mplayer_talk(mtmp)
  282. register struct monst *mtmp;
  283. {
  284.     char pbuf[BUFSZ];
  285.  
  286.     if(mtmp->mpeaceful) return; /* will drop to humanoid talk */
  287.  
  288.     Strcpy(pbuf, "Talk? -- ");
  289.     if(pl_character[0] == highc(*mtmp->data->mname)) { /* same kind */
  290.          switch(rn2(4)) {
  291.            case 0: Strcat(pbuf, "I can't win, and neither will you!");
  292.                break;
  293.            case 1: Strcat(pbuf, "You don't deserve to win!");
  294.                break;
  295.            case 3: Strcat(pbuf, "Mine should be the honor, not yours!");
  296.                break;
  297.          }
  298.     } else {
  299.          switch(rn2(4)) {
  300.            case 0: Strcat(pbuf, "The low-life wants to talk, eh?");
  301.                break;
  302.            case 1: Strcat(pbuf, "Fight, scum!");
  303.                break;
  304.            case 3: Strcat(pbuf, "Here is what I have to say!");
  305.                break;
  306.          }
  307.     }
  308.     pline(pbuf);
  309. }
  310.  
  311. /*mplayer.c*/
  312.